/*
 * EBFV1-hyperbolic.h
 *
 *  Created on: 09/01/2009
 *      Author: rogerio
 */

#ifndef EBFV1HYPERBOLI_H_
#define EBFV1HYPERBOLI_H_

#include "Hyperbolic_equation.h"
#include "HighOrderApproximation.h"

namespace PRS{
	class EBFV1_hyperbolic : public Hyperbolic_equation{
	public:

		EBFV1_hyperbolic();
		EBFV1_hyperbolic(PhysicPropData*, SimulatorParameters*, MeshData*, OilProductionManagement*, TMesh* pTMesh_data);
		~EBFV1_hyperbolic();
		virtual double solver(TMesh* pTMesh_data, double&);

	protected:

		//!brief Main functions related to the advective equation presented in order that they must be called.

		/*! brief Calculates mid-edges velocity field for domain "dom"
		 * \param dom Domain's flag
		 * \param dim Mesh dimension
		 * \param pTMesh_data Pointer to mesh data structure
		 */
		double calculateVelocityField(int dom, int dim, TMesh* pTMesh_data);

		/*! brief Calculate Nodal fluxes for each domain "dom"
		 * \param dom Domain's flag
		 * \param dim Mesh dimension
		 * \param pTMesh_data Pointer to mesh data structure
		 */
		double calculateIntegralAdvectiveTerm(int dom, int dim, TMesh* pTMesh_data);

		/*! brief Calculate new saturation field
		 * \param dom Domain's flag
		 * \param dim Mesh dimension
		 * \param pTMesh_data Pointer to mesh data structure
		 */
		double saturationTimeAdvance(TMesh* pTMesh_data, double delta_T);

		/*! brief Calculate nodal saturation gradient. Nodes over domain's boundaries have the same gradient value
		 * \param pTMesh_data Pointer to mesh data structure
		 */
		double calculateSaturationGradient(TMesh* pTMesh_data);

		/*! brief Sets to zero all nodal fluxes
		 * \param dom Domain's flag
		 * \param pTMesh_data Pointer to mesh data structure
		 */
		void resetNodalNonviscTerms(int dom, TMesh* pTMesh_data);

		/*! brief returns CFL constrained time-step
		 */
		double getTimeStep() const{
			return delta_t;
		};

		/*! brief set CFL constrained time-step
		 * \param dt time-step
		 */
		void setTimeStep(double dt){
		#ifdef __SEKKFORBUGS__
			if (dt<0){
				throw Exception(__LINE__,__FILE__,"Negative time-step!!!!\n");
			}
		#endif
			delta_t = dt;
		}

		/*! brief As simulation needs the smaller time-step, initialize it with a very high value. Specially for heterogeneous domains
		 */
		void resetTimeStep(){
			delta_t = 1e+8;
		}

		double delta_t;
		PetscErrorCode ierr;
		SimulatorParameters* pSimPar;
		PhysicPropData* pPPData;
		OilProductionManagement *pOPManager;
		HighOrderApproximation *pHOApproximation;
	};
}
#endif /* EBFV1HYPERBOLI_H_ */
